import threading
from typing import Optional

from common.exception_helper import error_handler_produce
from common.produce_logger import debug_produce
from db_tool.db_config import TableName
from db_tool.db_handler import DbHandler
from personal_tool.data_result import DataResult

db = DbHandler()


class CameraParams:
    """
    相机参数单例类，线程安全
    """
    _instance: Optional['CameraParams'] = None
    _lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:  # 双重检查锁定
                    cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        if not hasattr(self, '_initialized'):
            self.reload_camera_params()
            self._initialized = True
            debug_produce("in CameraParams.__init__(): 相机参数初始化完成")

    def reload_camera_params(self):
        """
        从数据库加载相机参数
        """
        result = db.get_data_one(TableName.cameraParams, {"key": "1"})
        if not result.state:
            debug_produce("in CameraParams.reload_camera_params(): 相机参数加载失败，使用默认值")
        data = result.data if result.data is not None else {}
        self.cameraWidth = data.get("cameraWidth", 2048)
        self.cameraHeight = data.get("cameraHeight", 4000)
        self.heightWidthRatio = data.get("heightWidthRatio", 1)
        self.mm2pix = data.get("mm2pix", 3.14)
        self.middleJointPos = data.get("middleJointPos", 1000)
        self.heightMin = data.get("heightMin", 1000)
        self.heightMax = data.get("heightMax", 1500)
        self.sizeScale = data.get("sizeScale", 5)
        debug_produce(f"表 {TableName.cameraParams.value} 加载完成: {data}")

    @error_handler_produce
    def update_params(self, newData: dict) -> DataResult:
        """
        更新相机参数
        :param newData: 新的参数字典
        :return: 是否更新成功
        """
        # 更新数据库
        result = db.update_data(TableName.cameraParams, {"key": "1"}, newData)
        if result.state:
            # 更新成功后重新加载参数
            self.reload_camera_params()
        return result
